package vn.smartoffice.promail.controller.dialog;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.Getter;
import lombok.Setter;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.resizers.configurations.Antialiasing;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.image.AImage;
import org.zkoss.image.Image;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zk.ui.select.Selectors;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zkplus.spring.DelegatingVariableResolver;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Window;

import vn.smartoffice.auth.UserService;
import vn.smartoffice.promail.entity.MailContact;
import vn.smartoffice.promail.entity.MailContactGroup;
import vn.smartoffice.promail.services.MailContactGroupService;
import vn.smartoffice.promail.services.MailContactService;
import vn.smartoffice.utils.DialogUtils;

@VariableResolver(DelegatingVariableResolver.class)
public class ContactDialogCtr {

	public static final int MAX_AVARTAR_WIDTH = 200;
	public static final int MAX_AVARTAR_HEIGHT = 220;

	@WireVariable private MailContactService mailContactService;
	@WireVariable private MailContactGroupService mailContactGroupService;
	@WireVariable private UserService userService;
	@Wire private Window contactDialog;

	@Setter private ListModelList<MailContactGroup> groupListModel;
	@Getter @Setter private MailContactGroup selectedGroup;
	@Getter private MailContact selectedContact;
	@Setter private Image img;
	private MailContactGroup currentGroup;

	public Image getImg() throws IOException {
		if (selectedContact.getId() == null || img != null) {
			return img;
		} else {
			return selectedContact.getAvatarImage();
		}
	}

	public ListModelList<MailContactGroup> getGroupListModel() {
		groupListModel();
		if (selectedContact.getMaiContactGroup() != null) {
			selectedGroup = selectedContact.getMaiContactGroup();
		} else if (currentGroup == null) {
			selectedGroup = groupListModel.get(0);
		} else {
			selectedGroup = currentGroup;
		}
		return groupListModel;
	}

	@AfterCompose
	public void afterCompose(@ContextParam(ContextType.VIEW) Component view,
			@ExecutionArgParam("maiContact") MailContact selectedContact,
			@ExecutionArgParam("currentGroup") MailContactGroup currentGroup) {
		Selectors.wireComponents(view, this, false);
		this.selectedContact = selectedContact;
		this.currentGroup = currentGroup;
	}

	@Command("uploadImage")
	@NotifyChange("img")
	public void uploadImage(@ContextParam(ContextType.TRIGGER_EVENT) UploadEvent event) throws IOException {
		Media media = event.getMedia();
		if (media instanceof Image) {
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			Thumbnails.of(media.getStreamData()).size(MAX_AVARTAR_WIDTH, MAX_AVARTAR_HEIGHT).outputQuality(1d)
					.keepAspectRatio(true).antialiasing(Antialiasing.ON).toOutputStream(os);
			img = new AImage("avatar.jpg", os.toByteArray());
			os.close();
		} else {
			Messagebox.show("Not an image: " + media, "Error", Messagebox.OK, Messagebox.ERROR);
		}
	}

	@Command("save")
	public void save() throws IOException {
		if (img != null) {
			selectedContact.setAvatar(img.getByteData());
		}
		selectedContact.setMaiContactGroup(selectedGroup);
		if (selectedContact.getId() == null) {
			mailContactService.save(selectedContact);
			DialogUtils.showNotification("contact.updateMessages");
		} else {
			mailContactService.update(selectedContact);
			DialogUtils.showNotification("contact.updateMessages");
		}

		Map<String, Object> dataArgs = new HashMap<>();
		dataArgs.put("contactId", selectedContact);
		contactDialog.detach();
		BindUtils.postGlobalCommand(null, null, "refreshMailContact", dataArgs);
	}

	@Command("cancel")
	public void cancel() {
		contactDialog.detach();
	}

	private void groupListModel() {
		List<MailContactGroup> listGroups = mailContactGroupService.findByUserId(userService.getCurrentUserId());
		groupListModel = new ListModelList<MailContactGroup>(listGroups);
	}

	/**
	 * Find index of mail contact in listModel.
	 *
	 * @param listModel
	 * @param contact
	 * @return -1 if not found
	 */
	/*
	 * private int findIndex(ListModelList<MailContactGroup> listModel,
	 * MailContactGroup mailContactGroup) { for (int i = 0; i <
	 * listModel.size(); i++) { if
	 * (mailContactGroup.getId().equals(listModel.get(i).getId())) { return i; }
	 * } return -1; }
	 */

}
